<template>
  <div class="detail-wrapper" :style="{'height': showSign? '100vh': 'auto', 'overflow': showSign? 'hidden': 'auto'}">
    <div class="detail-header">
      <span class="back" @click="back"><i class="el-icon-arrow-left">返回</i></span>
      查看进度
    </div>
    <div class="detail-main">
      <div v-for="item in processList" :key="item.id" class="status-wrapper" :class="{'notcircle': (processDetail.modelId === '1' && item.step === 5) || (processDetail.modelId === '2' && item.step === 3), 'done': (item.step < currentStep) || (processDetail.modelId === '1' &&item.step === 5 && processDetail.status === 10) || (processDetail.modelId === '2' && item.step === 3 && processDetail.status === 10), 'current': (item.step + 1) === currentStep && (!(processDetail.modelId === '2' && item.step === 3 && processDetail.status === 10)) && (!(processDetail.modelId === '2' && item.step === 0 && processDetail.status === 10))}">
        <div class="status" @click="openSlide(item)">
          <div class="status-header clearfix">
            {{item && item.description}}
            <span v-if="item.step > 0" style="float:right;padding-right:32px;" :style="{'color': item.status === 0? '#959595': item.status === 1? '#1890FF': '#FF4D4F'}">
              {{item.status === 0? (item.step === 1 && processDetail.modelId === '1')? '待签名': (item.step === 1 && processDetail.modelId === '2') ?'待签收': '待审核': item.status === 1? '已通过': '已驳回'}}
            </span>
          </div>
          <div class="status-content">
            <div class="owner" v-if="item.step === 0" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              文件名称：<span style="color: #262626">{{processDetail.name}}</span>
            </div>
            <div class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              执行人：<span style="color: #262626">{{item.candidatesName}}</span>
            </div>
            <div v-if="item.step === 0 && processDetail.modelId === '2'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              文件类型：<span style="color: #262626">{{processDetail.formData[1].val}}</span>
            </div>
            <div v-if="item.step === 0 && processDetail.modelId === '2'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              相应数量：<span style="color: #262626">{{processDetail.formData[2].val}}</span>
            </div>
            <div v-if="item.step === 0 && processDetail.modelId === '2'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              文件列表：<span style="color: #262626">{{processDetail.formData[3].val}}</span>
            </div>
            <div v-if="item.step === 0 && processDetail.modelId === '2'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              是否上传坚果云：<span style="color: #262626">{{processDetail.formData[4].val}}</span>
            </div>
            <div v-if="item.step === 0 && processDetail.modelId === '2'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              坚果云地址：<span style="color: #262626">{{processDetail.formData[5].val}}</span>
            </div>
            <div v-if="item.step === 1 && processDetail.modelId === '1'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              已签名：<span style="color: #262626">{{item.operatorName}}</span>
            </div>
            <div v-if="item.step === 3 && processDetail.modelId === '2'" class="owner" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              已签收：<span style="color: #262626">{{item.operatorName}}</span>
            </div>
            <div class="owner" v-if="item.step === 0 && processDetail.modelId === '1'" style="margin-bottom: 16px;color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">
              抄送人员：<span style="color: #262626">{{processDetail.ccNames}}</span>
            </div>
            <div class="file" v-if="(item.step === 0 || ((item.step === 1 || item.step === 5) && processDetail.modelId === '1') || (item.step === 3 && processDetail.modelId === '2')) && item.step <= processDetail.step">
              <p style="color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">附件：</p>
              <div v-for="file in processDetail.fileList" :key="file.id">
                <span @click.stop="viewPDF(file, item)">{{file.name}}</span>
              </div>     
            </div>
            <div class="remark">
              <p class="title" style="color: #8C8C8C;font-size: 14px;line-height: 18px;font-weight: normal;">{{item.step === 0 ? '备注内容': '审核意见'}}：</p>
              <p class="word">{{item.step === 0? processDetail.modelId === '1'? processDetail.formData[1].val: processDetail.formData[6].val :item.remark}}</p>
            </div>
            <div class="clearfix" v-if="item.history && item.history.length > 0">
              <div class="history-btn" @click.stop="item.showHistory = !item.showHistory;">历史消息<i v-if="!item.showHistory" class="el-icon-arrow-down"></i><i v-if="item.showHistory" class="el-icon-arrow-up"></i></div>
            </div>
            <div class="history" v-if="item.showHistory">
              <div v-for="historyItem in item.history" :key="historyItem.id">
                <div class="time">{{historyItem.completeDate}} {{historyItem.completeTime}}</div>
                <div class="content">
                  <div class="left" style="color:#262626;font-size: 14px;line-height: 30px;font-weight: normal;">{{historyItem.status === 1? '通过': '驳回'}}：</div>
                  <div class="right">{{historyItem.remark}}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="sign-dialog" v-if="showSign">
      <div class="mask"></div>
      <div class="sign-wrapper" ref="signwapper">
        <div class="user-action">
          <div>
            <el-tooltip effect="dark" content="放大" placement="bottom">
              <i class="el-icon-plus" @click="checkHasSign(zoomIn)"></i>
            </el-tooltip>
            <el-tooltip effect="dark" content="缩小" placement="bottom">
              <i class="el-icon-minus" @click="checkHasSign(zoomOut)"></i>
            </el-tooltip>
            <el-tooltip effect="dark" content="旋转" placement="bottom">
              <i class="el-icon-refresh-right" @click="checkHasSign(rotate)"></i>
            </el-tooltip>
            <el-tooltip effect="dark" content="下载" placement="bottom">
              <img v-if="canDownload || isSignUser" src="../../../assets/img/download.png" @click="downloadFile" alt="">
            </el-tooltip>
            <el-tooltip effect="dark" content="保存" placement="bottom">
              <img v-if="(currentOpenStep === 1 && canSign) || (currentOpenStep === 5 && canStamp)" @click="saveSign" src="../../../assets/img/sign-icon.png" alt="">
            </el-tooltip>
            <el-tooltip effect="dark" content="关闭" placement="bottom">
              <img src="../../../assets/img/close.png" @click="closePDF" alt="">
            </el-tooltip>
          </div>
        </div>
        <div class="loading-process" v-if="loaded !== total">
          <div class="progress" :style="{'width': (loaded* 100 / total + '%')}"></div>
        </div>
        <div id="canvas-contain">
          <div class="canvas-wrapper signPlace" :style="{'height': canvasHeight + 'px', 'width': canvasWidth + 'px'}" v-for="idx in canvasNum" :key="idx">
            <canvas :ref="'canvas' + idx"></canvas>
            <div :class="{'signPlace': canSign || canStamp, 'stamphover': canStamp}" @click.stop="addSign($event,idx)"></div>
            <div v-if="canSign">
              <div v-for="(sign, signIdx) in signCollect[idx-1]" :key="signIdx" class="sign clearfix" :style="{'left': sign.signLocationX + 'px', 'top': sign.signLocationY + 'px'}" @mousedown="startMove($event, sign)" @mouseup="endMove">
                {{userInfo.realName}}<i class="el-icon-close" @click="delSign(idx, signIdx)"></i><br>
                <span style="font-size: 14px;">{{thisDay()}}</span>
              </div>
            </div>
            <div v-if="canStamp">
              <div v-for="(sign, signIdx) in signCollect[idx-1]" :key="signIdx" class="stamp clearfix" :style="{'background-image': 'url(' + getUrl() + ')', 'left': sign.signLocationX + 'px', 'top': sign.signLocationY + 'px'}" @mousedown="startMove($event, sign)" @mouseup="endMove">
                <i class="el-icon-close" @click="delSign(idx, signIdx)"></i><br>
                <span style="font-size: 14px;position:absolute;top: 34px;left: 33px;color:red;">{{thisDay()}}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="slide-main" v-if="showSlide">
      <div ref="slide" class="mask" @click="closeSlide"></div>
      <div class="main" :class="animationName">
        <div class="slide-header">
          <span class="back" @click="closeSlide"><i class="el-icon-close"></i></span>
          审核
        </div>
        <div class="content-wrapper">
          <div class="content">
             <div class="status-header">
              {{currentStepItem && currentStepItem.description}}
            </div>
            <div class="status-content">
              <div class="owner">
                执行人：{{currentStepItem && currentStepItem.candidatesName}}
              </div>
              <div class="file">
                <p>附件：</p>
                <div class="file-wrapper">
                  <div v-for="file in processDetail.fileList" :key="file.id">
                    <span @click.stop="viewPDF(file, currentStepItem)">{{file.name}}</span>
                  </div>    
                </div> 
              </div>
              <div class="remark" v-if="!(processDetail.modelId === '2' && currentStepItem.step === 3)">
                <p class="title">备注内容：</p>
                <el-input v-model="audit.remark" resize="none" style="margin-top: 12px;" type="textarea" :rows="4" placeholder="请输入内容"></el-input>
              </div>
            </div>
          </div>
        </div>
        <div class="user-action">
          <div class="left" @click="saveAudit(true)">{{(processDetail.modelId === '2' && currentStepItem.step === 3) ? '签收': '通过'}}</div>
          <div class="right" v-if="currentStep > 1" @click="saveAudit(false)">驳回</div>
          <div class="right" v-if="currentStep === 1" @click="closeSlide">取消</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import dingMixin from  '@/mixins/ding'
import formUtil from "@/utils/formUtil";
import {dateUtil} from '@/utils/dateUtil'

export default {
  data() {
    return {
      showSign: false,
      showSlide: false,
      animationName: 'open',
      processList: [],
      currentStep: 0,
      audit: {
        processId: '',
        taskId: '',
        action: true,
        remark: '',
        signInfos: []
      },
      processDetail: {
        fileList: []
      },
      canMove: false,
      mouseX: 0,
      mouseY: 0,
      originMouseX: 0,
      originMouseY: 0,
      canvasNum: 0,
      signCollect: [],
      canvasHeight: 0,
      canvasWidth: 0,
      currentSign: null,
      originSignMouseX: 0,
      originSignMouseY: 0,
      total: 100,
      loaded: 0,
      canSign: false,
      canStamp: false,
      currentPDF: '',
      currentOpenStep: '',
      isSignUser: false,
      currentStepItem: {},
      currentPDFStream: null,
      defaultScale:1,
      defaultRotation: 0
    }
  },
  mixins: [dingMixin],
  computed:{
    canDownload() {
      return (this.userInfo.roleIdList && this.userInfo.roleIdList.includes('1302813747899891713')) || this.userInfo.dingId === this.processDetail.initiator
    }
  },
  async mounted() {
    this.getData();
  },
  methods:{
    getUrl() {
      return 'https://livolo-office.oss-cn-hangzhou.aliyuncs.com/1303170530497646593.png?t=' + (new Date().getTime());
    },
    thisDay() {
      return dateUtil.thisDay();
    },
    zoomIn() {
      if(this.defaultScale >= 1.49) return;
      this.defaultScale += 0.1;
      this.renderPDFPreview();
    },
    zoomOut() {
      if(this.defaultScale <= 0.51) return;
      this.defaultScale -= 0.1;
      this.renderPDFPreview();
    },
    zoomOut() {
      if(this.defaultScale <= 0.51) return;
      this.defaultScale -= 0.1;
      this.renderPDFPreview();
    },
    rotate() {
      this.defaultRotation += 90;
      this.renderPDFPreview();
    },
    checkHasSign(callback) {
      let collect = [];
      this.signCollect.forEach((arr) => {
        if(arr.length > 0) collect.push(...arr);
      })
      if(collect.length > 0) {
        formUtil.submitConfirm('当前正在处于签名或者盖章中，缩放旋转将清除签名或盖章，是否继续？', async ()=> {
          callback()
        })
      }else {
        callback()
      }
    },
    resetPDF() {
      formUtil.submitConfirm('签名或者盖章时需要恢复到原始状态，确定要恢复吗？', async ()=> {
        this.defaultRotation  = 0;
        this.defaultScale = 1;
        this.renderPDFPreview();
      })
    },
    closePDF() {
      this.showSign = false;
      this.signCollect = [];
      this.canvasNum = 0;
    },
    viewPDF(file, item) {
      this.currentOpenStep = item.step;
      this.currentPDF = file;
      this.canSign = false;
      this.canStamp = false;
      if(this.processDetail.step === 1 && this.processDetail.status === 1 && this.processDetail.modelId === '1') {
        if(item.step === 1) {
          let candidatesId = item.candidatesId.split(',')
          if(candidatesId.includes(this.userInfo.dingId)) {
            this.canSign = true;
            this.audit.processId = item.processId;
            this.audit.taskId = item.id;
            this.audit.remark = '';
            this.audit.signInfos = [];
          }
        }
      }
      if(this.processDetail.step === 5 && this.processDetail.status === 1 && this.processDetail.modelId === '1') {
        if(item.step === 5) {
          let candidatesId = item.candidatesId.split(',')
          if(candidatesId.includes(this.userInfo.dingId)) {
            this.canStamp = true;
            this.audit.processId = item.processId;
            this.audit.taskId = item.id;
            this.audit.remark = '';
            this.audit.signInfos = [];
          }
        }
      }

      this.showSign = true;
      this.$nextTick(() => {
        this.getPDF(file.signUrl, file.size)
      });
    },
    async saveSign() {
      this.audit.action = true;
      this.signCollect.forEach((arr) => {
        if(arr.length > 0) {
          this.audit.signInfos.push(...arr);
        }
      })
      if(this.audit.signInfos.length === 0) return this.$message.error('请签名后再保存');
      if (!(await this.$httpN.postB('audit/signgragh/sign', this.audit))) return;
      formUtil.submitSuccess('签名成功');
      this.closePDF();
      this.getData();
    },
    getPDF(url, size) {
      let that = this;
      var url = url;
      this.defaultScale = 1;
      this.defaultRotation = 0;
      var pdfjsLib = window['pdfjs-dist/build/pdf'];
      pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://livolo-office.oss-cn-hangzhou.aliyuncs.com/pdf.worker.js';
      var loadingTask = pdfjsLib.getDocument({
        url: url,
        length: parseInt(size)
      });
      loadingTask.onProgress = ({loaded,total}) => {
        this.total = parseInt(size);
        this.loaded = loaded
      };
      loadingTask.promise.then(function(pdf) {
        that.currentPDFStream = pdf;
        that.renderPDFPreview();
      });
    },
    renderPDFPreview() {
      this.canvasNum = this.currentPDFStream.numPages;
      this.signCollect = [];
      while(this.signCollect.length <this.currentPDFStream.numPages) {
        this.signCollect.push([])
      }
      this.$nextTick(() => {
        for(let i = 1; i <= this.currentPDFStream.numPages; i++) {
          this.renderPDF(this.currentPDFStream, i)
        }
      })
    },
    addSign($event,idx) {
      if(this.defaultScale !== 1 || this.defaultRotation !== 0) return this.resetPDF();
      if(!this.canSign && !this.canStamp) return;

      let targetWidth = this.canStamp? 140: 100;
      let targetHeight = this.canStamp? 84: 48;

      let sign = {
        fileId: this.currentPDF.id,
        pageNo: idx,
        signLocationX: $event.offsetX,
        signLocationY: $event.offsetY,
      }

      if(sign.signLocationX < 0) {
        sign.signLocationX = 0;
      }
      if(sign.signLocationY < 0) {
        sign.signLocationY = 0;
      }
      if(sign.signLocationX > (this.canvasWidth - targetWidth)) {
        sign.signLocationX = (this.canvasWidth - targetWidth);
      }
      if(sign.signLocationY > (this.canvasHeight - targetHeight)) {
        sign.signLocationY = (this.canvasHeight - targetHeight);
      }

      this.signCollect[idx - 1].push(sign)
    },
    delSign(idx, signIdx) {
      this.signCollect[idx-1].splice(signIdx, 1);
    },
    renderPDF(pdf, num) {
      let that = this;
      pdf.getPage(num).then(function(page) {
        var viewport = page.getViewport({scale: that.defaultScale, rotation: that.defaultRotation});
        let canvas = that.$refs['canvas' + num][0]
        let context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        that.canvasWidth = viewport.width;
        that.canvasHeight = viewport.height;
        let renderContext = {
          canvasContext: context,
          viewport: viewport
        };
        var renderTask = page.render(renderContext);
      });
    },
    moveMouse($event) {
      if(this.canMove) {
        this.currentSign.signLocationX = $event.clientX - this.originMouseX;
        this.currentSign.signLocationY = $event.clientY - this.originMouseY;
      }
    },
    startMove($event, sign) {
      this.canMove = true;
      this.currentSign = sign;
      this.originMouseX = $event.clientX;
      this.originMouseY = $event.clientY;
      this.originSignMouseX = sign.signLocationX;
      this.originSignMouseY = sign.signLocationY;

      let targetWidth = this.canStamp? 140: 100;
      let targetHeight = this.canStamp? 84: 48;

      window.onmousemove = (e) => {
        if(!this.canMove) return 
        this.currentSign.signLocationX = this.originSignMouseX + e.clientX - this.originMouseX;
        this.currentSign.signLocationY = this.originSignMouseY + e.clientY - this.originMouseY;
        
        if(this.currentSign.signLocationX < 0) {
          this.currentSign.signLocationX = 0;
          this.endMove();
        }
        if(this.currentSign.signLocationY < 0) {
          this.currentSign.signLocationY = 0;
          this.endMove();
        }
        if(this.currentSign.signLocationX > (this.canvasWidth - targetWidth)) {
          this.currentSign.signLocationX = (this.canvasWidth - targetWidth);
          this.endMove();
        }
        if(this.currentSign.signLocationY > (this.canvasHeight - targetHeight)) {
          this.currentSign.signLocationY = (this.canvasHeight - targetHeight);
          this.endMove();
        }
      }

      this.$refs.signwapper.onscroll = (e) => {
        this.endMove();
      }
    },
    endMove() {
      this.canMove = false;
      window.onmousemove = (e) => {};
      this.$refs.signwapper.onscroll = (e) => {};
    },
    openSlide(item) {
      this.currentOpenStep = item.step;
      if(this.processDetail.status !== 1) return;
      let owner = this.currentStepItem.candidatesId.split(',');
      if(!owner.includes(this.userInfo.dingId) || item.step !== this.currentStep) return;
      this.audit.processId = item.processId;
      this.audit.taskId = item.id;
      this.audit.signInfos = [];
      this.audit.remark = '';
      this.showSlide = true;
      this.$nextTick(() => {
        this.$refs.slide.style.opacity = 0.5;
      })
    },
    closeSlide() {
      this.animationName = 'close';
      this.$refs.slide.style.opacity = 0;
      setTimeout(() => {
        this.showSlide = false;
        this.animationName = 'open';
      }, 225)
    },
    back() {
      this.$router.go(-1);
    },
    async saveAudit(type) {
      this.audit.action = type;
      if (!(await this.$httpN.postB("audit/process/audit", this.audit))) return;
      formUtil.submitSuccess("审核成功");
      window.NEEDREFRESH = true;
      this.closeSlide();
      this.getData();
    },
    async getData() {
      this.processList = [];
      let result = await this.$httpN.postQ('audit/process/info', {processId: this.$route.params.id})
      this.processDetail = result;
      let start = {
        candidatesName: result.initiatorName,
        remark: result.remark,
        description: result.modelId === '1'? '创建签章申请': '创建文件签发',
        status: 1,
        step: 0
      }
      this.currentStep = result.step;
      let process = await this.$httpN.postB('audit/task/list', {processId: this.$route.params.id});
      process.forEach((item) => {
        item.showHistory = false;
        if(item.step === this.currentStep) this.currentStepItem = item;
      });
      this.processList.push(start, ...process);
      if(this.processDetail.modelId === '2') {
        let signArr = process[2].candidatesId.split(',');
        this.isSignUser = signArr.includes(this.userInfo.dingId);
      }
      if(this.processDetail.modelId === '1') {
        let signArr = process[0].candidatesId.split(',');
        this.isSignUser = signArr.includes(this.userInfo.dingId);
      }
    },
    async downloadFile() {//跨域文件路径、下载到本地的文件名
      if(this.processDetail.modelId === '1') {
        if(this.processDetail.expireTime && ((new Date()) > (new Date(this.processDetail.expireTime)))) return formUtil.submitError('文件已过期,无法下载');
      }

      let that = this.currentPDF;
      var x = new XMLHttpRequest();
      x.open("GET", that.signUrl, true);
      x.responseType = 'blob';
      x.onload=function(e) {
        var url = window.URL.createObjectURL(x.response)
        var a = document.createElement('a');
        a.href = url;
        a.download = that.name;
        a.click()
      }
      x.send();

      if(this.isSignUser && this.processDetail.status === 1 && this.processDetail.step === 3) {
        let item = this.processList[3];
        if (!(await this.$httpN.postB("audit/process/audit", {
          processId: item.processId,
          taskId: item.id,
          action: true,
        }))) return;
        formUtil.submitSuccess("签收成功");
        window.NEEDREFRESH = true;
        this.closeSlide();
        this.getData();
      }
    },
  }
}
</script>

<style lang="scss" scoped>
  .detail-wrapper{
    background: #F5F5F7;
    min-height: 100vh;
    .detail-header{
      height: 64px;
      background: #00A0E9;
      font-size: 18px;
      font-weight: 500;
      color: #FFFFFF;
      line-height: 64px;
      text-align: center;
      position: relative;
      .back{
        font-size: 16px;
        font-weight: 500;
        color: #FFFFFF;
        line-height: 22px;
        position: absolute;
        left: 32px;
        top: 21px;
        cursor: pointer;
      }
    }
    .detail-main{
      padding: 0 92px;
      .status-wrapper{
        padding: 24px 0;
        position: relative;
        &::before{
          content: '';
          display: block;
          width: 8px;
          height: 100%;
          position: absolute;
          left: -42px;
          top: 0;
          background: #EDEDED;
        }
        &::after{
          content: '';
          display: block;
          width: 28px;
          height: 28px;
          position: absolute;
          left: -52px;
          bottom: -14px;
          background: #FFF;
          border: 4px solid #EDEDED;
          border-radius: 50%;
          z-index:2;
        }
        &.notcircle::after{
          content: none;
        }
        &.done::after{
          border-color: #91D5FF;
        }
        &.done::before{
          background: #91D5FF;
        }
        &.current::after{
          border-color: #009EFF;
        }
      }
      .status{
        background: #FFF;
        border-radius: 14px;
        box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.03), 0px 6px 16px -8px rgba(0, 0, 0, 0.08);
        .status-header{
          line-height: 64px;
          height: 64px;
          font-size: 16px;
          font-weight: bold;
          color: #262626;
          padding-left: 32px;
          border-bottom: 2px solid #F3F3F3;
        }
        .status-content{
          padding: 24px 32px;
          .history-btn{
            cursor: pointer;
            line-height: 24px;
            position: relative;
            top: -24px;
            text-align: right;
            font-size: 16px;
            color: #8C8C8C;
            float:right;
            i{
              margin-left:5px;
            }
          }
          .history{
            >div{
              border-top: 1px solid #DFDFE0;
              padding-top: 16px;
              margin-bottom:16px;
              .time{
                font-size: 14px;
                color: rgba(0, 0, 0, 0.65);
                line-height: 22px;
              }
              .content{
                margin-top: 12px;
                display:flex;
              }
              .left{
                width:52px;
                font-size: 22px;
                font-weight: bold;
                color: #262626;
                line-height: 30px;
              }
              .right{
                flex: 1;
                font-size: 14px;
                color: rgba(0, 0, 0, 0.65);
                line-height: 30px;
              }
            }
          }
          .owner{
            font-size: 16px;
            font-weight: 500;
            color: #262626;
            font-weight: bold;
          }
          .file{
            p{
              font-size: 16px;
              font-weight: 500;
              color: #262626;
              margin: 0;
              margin-top: 16px;
              font-weight: bold;
              margin-bottom:8px;
            }
            >div{
              margin-top: 5px;
            }
            span{
              font-size: 14px;
              color: #00A0E9;
              line-height: 22px;
              cursor: pointer;
              display:inline-block;
              margin-top: 5px;
            }
          }
          .remark{
            p{
              margin: 0;
            }
            .title{
              font-size: 16px;
              font-weight: 500;
              color: #262626;
              margin-top: 16px;
              font-weight: bold;
            }
            .word{
              margin-top: 8px;
              font-size: 14px;
              font-weight: 400;
              color: #000000;
            }
          }
        }
      }
    }
    .slide-main{
      height: 100vh;
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100%;
      z-index: 10;
      .mask{
        background: rgb(0,0,0);
        height: 100%;
        position: absolute;
        top:0;
        left:0;
        transition: all 225ms;
        width: 100%;
        opacity: 0;
      }
      .main{
        position: absolute;
        width: 480px;
        height: 100%;
        top: 0;
        right: 0;
        background: #FFF;
        .slide-header{
          height: 64px;
          background: #00A0E9;
          font-size: 18px;
          font-weight: 500;
          color: #FFFFFF;
          line-height: 64px;
          text-align: center;
          position: relative;
          .back{
            font-size: 22px;
            font-weight: 500;
            color: #FFFFFF;
            line-height: 22px;
            position: absolute;
            left: 32px;
            top: 21px;
            cursor: pointer;
          }
        }
        .content-wrapper{
          height: calc(100vh - 64px);
          background: #FFF;
          padding: 32px;
          .content{
            background: #FFF;
            border-radius: 14px;
            max-height: calc(100vh - 220px);
            overflow: auto;
            box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.03), 0px 6px 16px -8px rgba(0, 0, 0, 0.08);
            .status-header{
              line-height: 64px;
              height: 64px;
              font-size: 22px;
              font-weight: bold;
              color: #262626;
              padding-left: 32px;
              border-bottom: 2px solid #F3F3F3;
            }
            .status-content{
              padding: 24px 32px;
              .owner{
                font-size: 16px;
                font-weight: 500;
                color: #262626;
                line-height: 22px;
                font-weight: bold;
              }
              .file{
                .file-wrapper{
                  max-height: 150px;
                  overflow: auto;
                }
                p{
                  font-size: 16px;
                  font-weight: 500;
                  color: #262626;
                  line-height: 22px;
                  margin: 0;
                  margin-top: 16px;
                  font-weight: bold;
                }
                >div{
                  margin-top: 5px;
                }
                span{
                  font-size: 14px;
                  color: #00A0E9;
                  line-height: 22px;
                  cursor: pointer;
                  display:inline-block;
                  margin-top: 5px;
                }
              }
              .remark{
                p{
                  margin: 0;
                }
                .title{
                  font-size: 16px;
                  font-weight: 500;
                  color: #262626;
                  line-height: 22px;
                  margin-top: 24px;
                  font-weight: bold;
                }
                .word{
                  margin-top: 8px;
                  font-size: 14px;
                  font-weight: 400;
                  color: rgba(0, 0, 0, 0.65);
                  line-height: 22px;
                }
              }
            }
          }
        }
        .user-action{
          position: absolute;
          bottom: 48px;
          right: 0;
          width: 100%;
          padding: 0 32px;
          >div{
            width: 196px;
            height: 50px;
            background: #1890FF;
            border-radius: 8px;
            font-size: 20px;
            color: #FFF;
            cursor: pointer;
            display: inline-block;
            line-height: 50px;
            text-align: center;
          }
          .right{
            margin-left:20px;
            background: #FF4D4F;
          }
        }
      }
    }
    .slide-main .open{
      animation: rtl-drawer-in .3s 1ms
    }
    .slide-main .close{
      animation: rtl-drawer-out .3s
    }
    .sign-dialog{
      height: 100vh;
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100%;
      z-index: 11;
      .mask{
        background: rgb(0,0,0);
        height: 100%;
        position: absolute;
        top:0;
        left:0;
        transition: all 225ms;
        width: 100%;
        opacity: 0.5;
      }
      .sign-wrapper{
        position: absolute;
        width: 100%;
        height: 100vh;
        overflow: auto;
        background: #EDEDF0;
        z-index: 2;
        padding-top: 32px;
        .user-action{
          height: 32px;
          position: fixed;
          z-index: 99;
          top: 0;
          left: 0;
          width: 100%;
          background: #F9F9FA;
          border-bottom: 1px solid #C8C8C8;
          img, i{
            width: 16px;
            display: inline-block;
            box-sizing: content-box;
            padding: 6px;
            cursor: pointer;
            &:hover{
              background: rgb(221, 222, 223);
            }
            font-weight: bold;
            font-size: 16px;
            vertical-align: bottom;
          }
          >div{
            position: absolute;
            right:30px;
            height: 28px;
            top: 2px;
          }
        }
        .loading-process{
          height: 2px;
          width: 100%;
          position: relative;
          .progress{
            top: 0;
            height:4px;
            width: 0;
            position: absolute;
            left: 0;
            transition: all .5s;
            background: #0AB4FF;
          }
        }
        #canvas-contain{
          margin-top: 10px;
        }
        .user-sign{
          top: 0;
          left: 0;
          position: absolute;
          width: 100px;
          height: 50px;
          border:1px solid black;
        }
        canvas{
          display: block;
        }
        .sign{
          position: absolute;
          top: 0;
          right: 0;
          border: 1px solid black;
          font-size: 20px;
          font-weight: bold;
          font-family: "SimSun";
          width: 100px;
          -webkit-user-select:none;
          -moz-user-select:none;
          -ms-user-select:none;
          user-select:none;
          cursor: move;
          i{
            cursor: pointer;
            float: right;
            margin-top: 1px;
          }
        }
        .stamp{
          position: absolute;
          top: 0;
          right: 0;
          width: 140px;
          height: 84px;
          cursor: move;
          background-size: contain;
          background-repeat: no-repeat;
          >i{
            position: absolute;
            right: -20px;
            top: 0;
            cursor: pointer;
            font-size: 20px;
          }
        }
        .canvas-wrapper{
          position: relative;
          margin: 0 auto 10px;
          box-shadow: rgba(32, 33, 36, 0.28) 0px 1px 6px 0px;
          .signPlace{
            cursor: url('../../../assets/img/sign-hover.png'), auto;
            position: absolute;
            top: 0;
            left:0;
            width: 100%;
            height: 100%;
          }
          .signPlace.stamphover{
            cursor: url('../../../assets/img/stamp-hover.png'), auto;
          }
        }
      }
    }
  }
</style>